<html>
<head>
  <title>Resource change events for encoding changes</title>
  <link rel="stylesheet" href="../default_style.css" type="text/css">
</head>
<body text="#000000" bgcolor="#ffffff">
<h1>Resource change events for encoding changes</h1>
<p><font size="-1">Last modified: August 27th, 2004</font> </p>
<p>This document is a place where to gather the requirements and plan a solution 
  for bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=59899">59899</a></p>
<h3>Things that affect the encoding of files</h3>
<ol>
  <li>the file's encoding as set by the user</li>
  <li>the file's content type 
    <ol>
      <li>the file's name</li>
      <li>the list of file specifications for a content type</li>
      <li>the content type default encoding</li>
      <li>the encoding information embedded in the file's contents</li>
    </ol>
  </li>
  <li>the parent's default encoding 
    <ol>
      <li>the file.encoding property</li>
      <li>the workspace encoding preference</li>
      <li>the project or folder default encoding project preference</li>
    </ol>
  </li>
</ol>
<h3>Scenarios where the encoding for a file could change</h3>
<ol>
  <li>the user changed the encoding (or set it to default) for a specific file 
    using the file's properties dialog <em> 
    <p> This is the most basic scenario - affects the IFile#setCharset operation. 
    </p>
    <p> <strong>Fix</strong>: instrument File#setCharset (the long-running version) 
      to mark the file as having encoding changes.</p>
    </em> </li>
  <li>the user changed the encoding (or set it to default) for a specific file 
    using the text editor action (Edit &gt; Encoding) <em> 
    <p> Although the user action is different, this is similar to the scenario 
      above.</p>
    <p> <strong>Fix</strong>: the same as in the case mentioned. </p>
    </em></li>
  <li>the user changed the default encoding (or set it to default) for a container 
    (folder, project) using the resource's properties dialog <em> 
    <p>Although this may not be easy to support, it is also a basic requirement. 
      Affected operation: IContainer#setDefaultCharset.</p>
    <p><strong>Planned fix</strong>: WorkspaceRoot/Project/Folder#setDefaultCharset 
      need to traverse all children and mark those that a) don't have an encoding 
      explicitly set and b) do not belong to any content type that provide a default 
      encoding as having encoding changes.</p>
    <p> <strong>Actual fix:</strong> as planned, except that no deltas are generated 
      for changes to the workspace root.</p>
    </em></li>
  <li>a file is moved to a different location, having a different file encoding 
    inherited from the parent <em> 
    <p>It is not clear we need any special support here. Not sure whether builders 
      and interesting listeners always simply treat a file being moved as a big 
      change and rebuild the affected model, or they just adjust their model correspondingly 
      (re: resource's path change), without recomputing anything. </p>
    <p><strong>Fix</strong>: no action required - listeners interested in encoding 
      changes should consider MOVED_FROM/TO deltas as indication the encoding 
      may have changed. </p>
    </em></li>
  <li>a direct change to the preferences file for a project (e.g. by manually 
    editing the file, or checking it out from the repository, etc), causing changes 
    to the encoding settings of projects, folders and/or files <em> 
    <p>This would cause preference change events to be broadcast. We would have 
      to capture such events and generate a corresponding resource change event. 
      One problem here is that we are in the context of a POST_CHANGE/PRE_DELETE 
      notification (workspace is closed for changes).</p>
    <p><strong>Planned fix</strong>: project preference changes in this case will 
      be sent while the workspace is still open for business. A project preference 
      change listener has then to (from inside an workspace operation) mark all 
      affected resources as having encoding changes. </p>
    <p> <strong>Actual fix:</strong> when the project preferences file that stores 
      the charset preferences is changed, we fire encoding change events (in a 
      background job) for *all* resources in the project, since we have no means 
      to figure out which ones actually changed.</p>
    </em></li>
  <li>the user promotes direct changes to the corresponding project preferences 
    file directly in the file system <em> 
    <p> The changes will be caught when the file is refreshed, but it may not 
      be possible to figure out what the previous values of properties were (for 
      instance, when the properties have never been loaded in memory before). 
      Other than that, is the same scenario as above. </p>
    <p> <strong>Fix</strong>: the same as in the case mentioned. </p>
    </em></li>
  <li>the user promotes direct changes to the corresponding project preferences 
    file between two Eclipse sessions <em> 
    <p> There will be no way to figure out what the previous values for the properties 
      were. No changes will be detected. </p>
    <p> <strong>Fix</strong>: none.</p>
    </em></li>
  <li>the user changed the default encoding (or set it to default, which is the 
    value of the file.encoding property) for the workspace using the preferences 
    dialog (<b>General &gt; Editors &gt; New text file encoding</b>) <em> 
    <p>A preference change listener would have to react appropriately by issuing 
      a resource change event for the workspace root (and all affected children!). 
      This is similar as the case where changes are made directly to the file.</p>
    <p> <strong>Planned fix</strong>: the same as in the case mentioned. </p>
    <p> <strong>Actual fix:</strong> the Platform/UI has been requested to use 
      IWorkspaceRoot#setDefaultCharset instead (bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=71742">71742</a>). 
      This handles the case the user changes its preferences but does not handle 
      the case preferences are imported. <strong><font color="#33A000">This needs 
      more work</font></strong>.</p>
    </em></li>
  <li>the very same preference is changed by directly editing the corresponding 
    preferences file between two Eclipse sessions <em> 
    <p>We would have to keep a copy of the preference value somewhere and check 
      it during startup. If it has changed, the same as above would have to be 
      done.</p>
    <p> <strong>Planned fix</strong>: during startup, compare the last workspace 
      encoding (need to remember that somewhere) and the new one. If it has changed, 
      mark the affected files accordingly. </p>
    <p> <strong>Actual fix:</strong> none.</p>
    </em> </li>
  <li>the VM started with default default encoding (the value of the file.encoding 
    system property) that was different than the one used in the previous session, 
    and the workspace root default encoding was not set <em> 
    <p> Similar to above. </p>
    <p> <strong>Planned fix</strong>: the same as in the case mentioned. </p>
    <p> <strong>Actual fix:</strong> none.</p>
    </em> </li>
  <li>a file that has its encoding determined from its contents (e.g. a XML file) 
    is modified, causing the resulting encoding to be different <em> 
    <p> A regular resource change event is already issued for the content change. 
      Should not have to do anything else. </p>
    <p><strong>Fix</strong>: no action required. Clients are expected to react 
      to content changes considering that the encoding may have changed.</p>
    </em></li>
  <li>a content type has its default encoding changed <em> 
    <p><strong>Planned fix</strong>: a preference change listener would have to 
      catch the event and produce the appropriate delta for every affected resource 
      in the whole workspace.</p>
    <p><strong>Actual fix</strong>: we listen for content type change events and produce the appropriate delta for every affected resource 
      in the whole workspace. We are not smart enough to avoid generating deltas for 
	  files that have a user-set encoding, which are not actually affected.</p>	  
    </em></li>
  <li>file specs are added to/removed from a content type that has a default encoding 
    set <em> 
    <p> Same as above. </p>
    <strong>Planned fix</strong>: the same as in the case mentioned. 
    <p><strong>Actual fix:</strong> when a change to a content type happens, encoding 
      change events will be generated (in a background job) for all files whose 
      names match the content type's current definition.This acknowledgedly misses 
      the case where a file ceases to belong to a content type that used to determine 
      its encoding.</p>
    </em></li>
  <li>a file name changes, and it stops/starts belonging to a given content type 
    <em> 
    <p>This is caught by the MODE_FROM/MOVED_TO case. Clients are expected to 
      recompute their internal state when a file has its name changed. </p>
    <p><strong>Fix</strong>: no action required. </p>
    </em></li>
  <li>a content type is added/removed between two sessions, causing the content 
    types (and default encoding) of some files to change.</li>
  <em> 
  <p> There would be no property/registry change events for that.</p>
  <p><strong>Fix</strong>: none.</p>
  </em> 
  <li>a content type that has a default charset definition is dynamically installed. 
    <em> 
    <p> The Resources plug-in is not expected to react properly on such situations 
      (it is not supposed to be dynamic-aware). </p>
    <p> <strong>Fix</strong>: none. </p>
    </em></li>
</ol>

<hr>
<h3>Notes from discussions on July 27th</h3>

<h4>Content Type (Runtime)</h4>
<ul>
  <li>new API for notification</li>
  <li>listener pattern</li>
  <li>when do notifications happen?</li>
  <li>no major technical difficulties</li>
  </ul>
  
<h4>File Encoding (Resources)</h4>

<p></p>
1) Catch and wrap/translate runtime events 
<ul>
  <li>catch events related to changes in the content type registry</li>
  <li>potential for VERY long operations</li>
  <li>walking the resource tree looking for matches based on file extension, etc</li>
  </ul>
  
<p></p>
2) React to preference changes 
<ul>
  <li>changes are made via the preference API and through the resource API (#setContents 
  and #refreshLocal)</li>
  <li>we store the following values in prefs:</li>
  <ol>
  <li>workspace encoding (instance prefs)</li>
  <li>non-default content types (instance prefs)</li>
  <li>project+children encodings (project prefs)</li>
  </ol>
  <li>ignore preference change events</li>
  <li>problem for #3 is that we need to generate a delta based on POST_CHANGE notification 
  (workspace tree is locked)</li>
  <li>project description file already has special code in #setContents and #refreshLocal 
  (#updateProjectDescription is called and this method determines whether or not 
  we are dealing with the project description file and if so then what action 
  to take)</li>
  <li>investigate adding a #updateProjectSettings method which does the same type 
  of thing for project settings files</li>
  </ul>

<p></p>
3) Implement new APIs 
<ul>
  <li>follow the begin/end operation template</li>
  <li>modify the ResourceInfos so they generate a delta</li>
  <li>do we have deltas for the workspace root?</li>
  <li>DeltaDataTree short-circuit returns in its compare</li>
  <li>if deltas are deep, we might not care for case of root (except for consistency) 
  - actually, although we spec'd more or less that we would do that, I don't actually 
  think we should propagate change events when the default encoding for containers 
  (root, projects, folders) change - only files. The specs can be reworded to 
  have this meaning. Although it is not the main motivation, it makes this problem 
  irrelevant.</li>
</ul>

<p></p>
4) Constuct the delta 
<ul>
  <li>do we need to hold onto an extra int/log in ResourceInfo as a timestamp/generation 
    count for the encoding?</li>
  <li>might be able to use bytes from the long we already have</li>
  <li>change the ResourceComparator to set the appropriate flags</li>
</ul>
</body>
</html>
